#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <pthread.h>

#define PORT 8080

void *connection_handler(void *);

int main() {
    int sockfd, newsockfd;
    struct sockaddr_in serv_addr, cli_addr;
    socklen_t clilen;
    pthread_t thread_id;

    sockfd = socket(AF_INET, SOCK_STREAM, 0);
    if (sockfd < 0) {
        perror("ERROR opening socket");
        exit(1);
    }

    bzero((char *) &serv_addr, sizeof(serv_addr));
    serv_addr.sin_family = AF_INET;
    serv_addr.sin_addr.s_addr = INADDR_ANY;
    serv_addr.sin_port = htons(PORT);

    if (bind(sockfd, (struct sockaddr *) &serv_addr, sizeof(serv_addr)) < 0) {
        perror("ERROR on binding");
        exit(1);
    }

    listen(sockfd, 5);
    clilen = sizeof(cli_addr);

    while (newsockfd = accept(sockfd, (struct sockaddr *) &cli_addr, &clilen)) {
        if (pthread_create(&thread_id, NULL, connection_handler, (void*) &newsockfd) < 0) {
            perror("ERROR on thread creation");
            return 1;
        }
    }

    if (newsockfd < 0) {
        perror("ERROR on accept");
        exit(1);
    }

    printf("Connection accepted");
    close(sockfd);
    return 0;
}

void *connection_handler(void *socket_desc) {
    int sock = *(int*)socket_desc;
    char buffer[256];
    ssize_t buf_size;
// ssize_t read(int fd,void *buf,size_t count)
//    1、如果读取成功，则返回实际读到的字节数。这里又有两种情况：一是如果在读完count要求字节之前已经到达文件的末尾，那么实际返回的字节数将 小于count值，但是仍然大于0；二是在读完count要求字节之前，仍然没有到达文件的末尾，这是实际返回的字节数等于要求的count值。
//    2、如果读取时已经到达文件的末尾，则返回0。
//    3、如果出错，则返回－1。
    while ((buf_size = read(sock, buffer, 255)) > 0) {
        printf("Message from sock %d: %s", sock, buffer);  // 打印消息和sock号
        bzero(buffer, 256);
    }

    if (buf_size == 0) {
        printf("Client on sock %d disconnected\n", sock);  // 已经到了文件末尾，也就是说断连了
    } else if (buf_size == -1) {
        perror("Receive failed");  // 接收出错
    }
    close(sock);
    return 0;
}
